// OpenArchive.h

#ifndef __OPEN_ARCHIVE_H
#define __OPEN_ARCHIVE_H



#include "Common/FileSystem/FileFind.h"

#include "Common/Archive/IArchive.h"

#include "ArchiveOpenCallback.h"
#include "LoadCodecs.h"

#include <atlbase.h>

#include <vector>
#include <memory>

namespace Common
{
namespace Archive
{

HRESULT GetArchiveItemBoolProp(IInArchive *archive, UINT32 index, PROPID propID, bool &result);
HRESULT IsArchiveItemFolder(IInArchive *archive, UINT32 index, bool &result);

struct CArc
{
  CComPtr<IInArchive> Archive;
  CString Path;
  CString DefaultName;
  int FormatIndex;
  int SubfileIndex;
  FILETIME MTime;
  bool MTimeDefined;
  CString ErrorMessage;

  CArc(): MTimeDefined(false) {}

  HRESULT GetItemPath(UINT32 index, CString &result) const;
  HRESULT GetItemMTime(UINT32 index, FILETIME &ft, bool &defined) const;
  HRESULT IsItemAnti(UINT32 index, bool &result) const
    { return GetArchiveItemBoolProp(Archive, index, kpidIsAnti, result); }

  HRESULT OpenStream(
    CCodecs *codecs,
    int formatIndex,
    IInStream *stream,
    ISequentialInStream *seqStream,
    IArchiveOpenCallback *callback);

  HRESULT OpenStreamOrFile(
    CCodecs *codecs,
    int formatIndex,
    bool stdInMode,
    IInStream *stream,
    IArchiveOpenCallback *callback);
};

struct CArchiveLink
{
	typedef std::vector<std::shared_ptr<CArc> > ArrayArcs ;
	ArrayArcs		Arcs;
	CStringVector	VolumePaths;
	UINT64			VolumesSize;
	bool			IsOpen;

  CArchiveLink(): VolumesSize(0), IsOpen(false) {}
  HRESULT Close();
  void Release();
  ~CArchiveLink() { Release(); }

  IInArchive *GetArchive() const 
  { 
	  if (Arcs.empty())
	  {
		  return NULL;
	  }
	  return Arcs.back()->Archive; 
  }

  HRESULT Open(
    CCodecs *codecs,
	const std::vector<int> &formatIndices,
    bool stdInMode,
    IInStream *stream,
    const CString &filePath,
    IArchiveOpenCallback *callback);

  HRESULT Open2(
    CCodecs *codecs,
    const std::vector<int> &formatIndices,
    bool stdInMode,
    IInStream *stream,
    const CString &filePath,
    IOpenCallbackUI *callbackUI);

  HRESULT ReOpen(
    CCodecs *codecs,
    const CString &filePath,
    IArchiveOpenCallback *callback);
};

}
}
#endif
